//-*-C++-*-
/***************************************************************************
 *
 *   Copyright (C) 2025 by Will Gauvin
 *   Licensed under the Academic Free License version 2.1
 *
 ***************************************************************************/

#ifndef __dsp_RescaleScaleOffsetDump_h_
#define __dsp_RescaleScaleOffsetDump_h_

#include "dsp/Rescale.h"
#include "FilePtr.h"

#include <vector>

namespace dsp {

  /**
   * @brief Dumps the scale and offset data from the Rescale operation of a pipeline.
   *
   * This will write the scales and offsets for the current start sample number of an output.
   * On @see Rescale the scales and offset are stored in polarisation (P) and then channel (F) ordering (i.e. PF)
   * and this class will dump the data in the same ordering but writing the offsets first and then the scales.
   *
   * To allow for varying time of when this is called the current sample number is
   * Also written out as a uint64_t (64bits) and the scales and offsets are IEEE 754
   * float 32 (i.e. 32 bits).
   *
   * Thus the size of each record is (64 bits + NPOL * NCHAN * 2 * 32 bits) / 8 bytes long
   *
   * Record structure is: [sample_number][offsets][scales]
   * where:
   *  [offsets] = [pol0,chan0 offset][pol0,chan1 offset]...[pol0,chanN offset][pol1,chan0 offset]...
   *  [scales] = [pol0,chan0 scale][pol0,chan1 scale]...[pol0,chanN scale][pol1,chan0 scale]...
   */
  class RescaleScaleOffsetDump : public Reference::Able
  {
  public:

    //! Default constructor
    RescaleScaleOffsetDump(const std::string& filename);

    virtual ~RescaleScaleOffsetDump () = default;

    /**
     * @brief the callback method used by the Rescale operation when scales and offsets have been updated.alignas
     *
     * @param rescale a pointer to the instance of the Rescale operation that has just updated the scales and offsets.
     */
    void handle_scale_offset_updated(Rescale* rescale);

  protected:
    //! pointer to the output file to write to.
    FilePtr output;

  private:
    //! Prepare buffer and write headers.
    void write_header (Rescale* rescale);

    //! buffer used internally to setup a record to write
    std::vector<char> buffer;

    //! indicator of whether header was written or not
    bool header_written{false};

  };

} // namespace dsp

#endif // __dsp_RescaleScaleOffsetDump_h_

